#include <stdio.h>
#include <string.h>
#include "modbus.h"

static int error_code = 0; // È«¾Ö±äÁ¿ÓÃÓÚ¼ÇÂ¼´íÎó´úÂë

/*
º¯Êý¹¦ÄÜ£º½âÎö´íÎó´úÂë
*/
void parse_error_code(void)
{
    switch (error_code) {
        case -1:
            printf("not local addr\r\n");
            break;
        case -2:
             printf("LRC check failed\r\n");
            break;
    }
}

/*
º¯Êý¹¦ÄÜ£ºÉè¶¨´Ó»úµØÖ·
*/

/*
º¯Êý¹¦ÄÜ£º½âÎömodbusÖ¡
*/

bool Modbus_FrameParse(const char *frame_raw, ModbusTypeDef *mod)
{
    // ½âÎö´Ó»úµØÖ·
          
            mod->slave_addr = (frame_raw[0] - '0') * 10 + (frame_raw[1] - '0');
            
            printf("slave addr: %d\r\n", mod->slave_addr);
            
            if (mod->slave_addr != LOCAL_ADDR) {
                
                error_code = -1;
                return false;
            }
            
            // ½âÎö¹¦ÄÜÂë
           
            mod->func_code = (frame_raw[2] - '0') * 10 + (frame_raw[3] - '0');
            printf("func code: %d\r\n", mod->func_code);
            
            // ½âÎöÊý¾Ý
            mod->len = (frame_raw[4] - '0') * 10 + (frame_raw[5] - '0');
            
          
            memset(mod->payload, 0, mod->payload_size);
            strncpy(mod->payload, frame_raw + 6, mod->len);
            printf("len: %d, %s\r\n", mod->len, mod->payload);
            
            // Ð£Ñé
            u8 lrc = 0;
            for (u16 i = 0;i < mod->len + 6; i++)
                lrc += frame_raw[i];
               
            u8 recv_lrc;
            sscanf(frame_raw + 7, "%hhx", &recv_lrc);
            
            //printf("LRC:%x, %x\r\n", lrc, recv_lrc);
            if (lrc != recv_lrc) {
                error_code = -2;
                return false;
            }
            
            return true;
}

/*
º¯Êý¹¦ÄÜ£º·â×°modbusÖ¡
*/
bool Modbus_FramePack(const ModbusTypeDef *mod, char *frame_pack)
{
    frame_pack[0] = mod->slave_addr / 10 % 10 + '0';
    frame_pack[1] = mod->slave_addr % 10 + '0';
    frame_pack[2] = mod->func_code / 10 % 10 + '0';
    frame_pack[3] = mod->func_code % 10 + '0';
    
    frame_pack[4] = mod->len / 10 % 10 + '0';
    frame_pack[5] = mod->len % 10 + '0';
    
    memcpy(frame_pack + 6, mod->payload, mod->len);
    
    u8 lrc = 0;
    for (u16 i = 0;i < mod->len + 6; i++)
        lrc += frame_pack[i];
    
    sprintf(frame_pack + 6 + mod->len, "%02hhx",  lrc);
    
    strcat(frame_pack, "\r\n");
    return true;
}
